const fs = require('fs')
const events = require('events')
const express = require('express')
const formidable = require('formidable')
const Sequelize = require('sequelize')
const AdmZip = require('adm-zip-iconv')
const sequelize = require('../../mysql')
const { Project, Page, Label, Menu, Module, API, Message } = require('../../model')
const router = express.Router()
const $event = new events.EventEmitter()

function unzipProject(path, projectId, callback) {
  const zip = new AdmZip(path, 'GBK')
  zip.extractAllTo(`./static/upload/${projectId}`, true)
  callback()
}
function createMessage(type, desc) {
  Message.create({
    type,
    desc
  })
}
/* 上传图片 */
router.post('/upload', (req, res, next) => {
  const form = new formidable.IncomingForm()
  form.uploadDir = './static/upload'
  form.keepExtensions = true
  form.parse(req, (err, fields, files) => {
    // const extname = path.extname(files.file.name)
    const newpath = `./static/upload/${files.file.name}`
    fs.rename(files.file.path, newpath, (err) => {
      return res.json({
        code: 200,
        msg: '上传成功',
        url: newpath.replace('./static', '')
      })
    })
  })
})
/* 项目管理 */
router.get('/projectList', async (req, res, next) => {
  const data = await Project.findAll()
  return res.json({
    code: 200,
    data
  })
})
/* 项目管理 */
router.get('/msgList', async (req, res, next) => {
  const { page, pageSize = 10 } = req.query
  const total = await Message.count()
  const data = await Message.findAll({
    offset: (page - 1) * pageSize,
    order: [['id', 'desc']],
    limit: page * pageSize
  })
  return res.json({
    code: 200,
    count: Math.ceil(total / pageSize),
    total,
    data
  })
})
router.post('/updateProject', async (req, res, next) => {
  const { name, id } = req.body
  if (id) {
    try {
      await Project.update({ name }, {
        where: {
          id
        }
      })
      return res.json({
        code: 200,
        msg: '修改成功'
      })
    } catch (err) {
      return res.json({
        code: 0
      })
    }
  } else {
    try {
      await Project.create({
        name
      })
      return res.json({
        code: 200,
        msg: '新增成功'
      })
    } catch (err) {
      return res.json({
        code: 0
      })
    }
  }
})
/* 模块管理 */

router.get('/ModuleList', async (req, res, next) => {
  const { projectId } = req.query
  const data = await Module.findAll({
    attributes: ['id', 'name', 'packageUrl', 'createdAt', 'projectId'],
    where: {
      projectId
    }
  })
  return res.json({
    code: 200,
    data
  })
})
router.post('/updateModule', async (req, res, next) => {
  const { name, packageUrl, id, projectId } = req.body
  if (id) {
    try {
      await Module.update({
        projectId,
        name,
        packageUrl
      }, {
        where: {
          id
        }
      })
      unzipProject(`./static/${packageUrl}`, id, () => {
        res.json({
          code: 200,
          msg: '修改成功'
        })
      })
    } catch (err) {
      return res.json({
        code: 0,
        msg: '操作失败'
      })
    }
  } else {
    try {
      await Module.create({
        projectId,
        name,
        packageUrl
      })
      unzipProject(`./static/${packageUrl}`, id, () => {
        res.json({
          code: 200,
          msg: '新增成功'
        })
      })
    } catch (err) {
      return res.json({
        code: 0,
        msg: '操作失败'
      })
    }
  }
})
/* 菜单管理 */
router.get('/menuList', async (req, res, next) => {
  const { projectId, parentId, type } = req.query
  let query = {}
  if (type) {
    const queryStr = !parentId ? true : `B.parentId=${parentId}`
    const data = await sequelize.query(`
    SELECT B.id,B.name,B.createdAt,B.projectId,B.parentId ,(SELECT A.name FROM menus A WHERE A.id=B.parentId) as parentName FROM menus B WHERE projectId=${projectId} AND  B.code IS NULL AND ${queryStr};
    `)
    return res.json({
      code: 200,
      data: data[0]
    })
  } else {
    query = {
      parentId: {
        [Sequelize.Op.eq]: null
      }
    }
  }
  const data = await Menu.findAll({
    attributes: ['id', 'name', 'code', 'createdAt', 'parentId'],
    order: [['id', 'desc']],
    where: {
      projectId,
      ...query
    }
  })
  return res.json({
    code: 200,
    data: data
  })
})

router.post('/updateMenu', async (req, res, next) => {
  const { name, code, id, parentId, projectId } = req.body
  const model = Menu
  if (id) {
    try {
      await model.update({ name, code, projectId, parentId }, {
        where: {
          id
        }
      })
      return res.json({
        code: 200,
        msg: '修改成功'
      })
    } catch (err) {
      return res.json({
        code: 0,
        msg: '操作失败'
      })
    }
  } else {
    try {
      await model.create({
        projectId,
        parentId,
        name,
        code
      })
      if (parentId) {
        createMessage('新增功能', name)
      }
      return res.json({
        code: 200,
        msg: '新增成功'
      })
    } catch (err) {
      return res.json({
        code: 0,
        msg: '操作失败'
      })
    }
  }
})

// 删除菜单、功能
router.post('/deleteMenu', async (req, res, next) => {
  const { id } = req.body
  await Menu.destroy({
    where: {
      id
    }
  })
  try {
    return res.json({
      code: 200,
      msg: '删除成功'
    })
  } catch (err) {
    return res.json({
      code: 0,
      msg: err
    })
  }
})

/* 标注 */
router.post('/delLabel', async (req, res, next) => {
  const { id } = req.body
  const data = await Label.destroy({
    where: {
      id
    }
  })
  return res.json({
    code: 200,
    data
  })
})
router.post('/addLabel', async (req, res, next) => {
  const { label, left, top, pageName, projectId } = req.body
  const result = await Page.findAll({
    where: {
      name: pageName
    }
  })
  let page = result.length ? result[0] : {}
  if (!result.length) {
    page = await Page.create({
      projectId,
      name: pageName
    })
  }
  const data = await Label.create({
    projectId,
    label,
    left,
    top,
    pageId: page.id
  })
  res.json({
    code: 200,
    data
  })
})
router.post('/updateLabel', async (req, res, next) => {
  const { label, left, top, id } = req.body
  const data = await Label.update({
    label,
    left,
    top
  }, {
    where: {
      id
    }
  })
  res.json({
    code: 200,
    data
  })
})
router.get('/labelList', async (req, res, next) => {
  const { pageName } = req.query
  const result = await Page.findAll({
    where: {
      name: pageName
    }
  })
  const page = result.length ? result[0] : {}
  if (!result.length) {
    return res.json({
      code: 200,
      data: []
    })
  } else {
    const data = await Label.findAll({
      where: {
        pageId: page.id
      }
    })
    return res.json({
      code: 200,
      data
    })
  }
})
/* 接口管理 */
router.post('/updateApi', async (req, res, next) => {
  const { name, id, apiUrl, subMenuId, projectId, postType, menuId, headerJSON, bodyJSON, result, desc } = req.body
  if (id) {
    try {
      await API.update({
        name, subMenuId, projectId, apiUrl, postType, menuId, headerJSON, bodyJSON, result, desc
      }, {
        where: {
          id
        }
      })
      createMessage('修改接口', name)
      res.json({
        code: 200,
        msg: '修改成功'
      })
    } catch (err) {
      return res.json({
        code: 0,
        msg: err
      })
    }
  } else {
    try {
      await API.create({
        name, subMenuId, projectId, apiUrl, postType, menuId, headerJSON, bodyJSON, result, desc
      })
      createMessage('新增接口', name)
      res.json({
        code: 200,
        msg: '新增成功'
      })
    } catch (err) {
      return res.json({
        code: 0,
        msg: err
      })
    }
  }
})

router.get('/apiList', async (req, res, next) => {
  const { projectId, page, pageSize = 10, subMenuId, menuId } = req.query
  const total = await API.count()
  const menuQuery = menuId ? `FIND_IN_SET(${menuId}, menuId)` : 1
  const subQuery = subMenuId ? `FIND_IN_SET(${subMenuId}, subMenuId)` : 1
  sequelize.query(`SELECT * FROM apis  WHERE ${menuQuery} And ${subQuery}  AND projectId = ${projectId}  
  order by id desc
  LIMIT ${(page - 1) * pageSize}, ${page * pageSize};`).then(data => {
  //  console.log(data)
    res.json({
      total,
      count: Math.ceil(total / pageSize),
      code: 200,
      data: data[0]
    })
  })
})

// 接口详情
router.get('/apiDetail', async (req, res, next) => {
  const { id } = req.query
  try {
    const result = await API.findAll({
      where: {
        id
      }
    })
    return res.json({
      code: 200,
      data: result[0]
    })
  } catch (err) {
    console.log(err)
    return res.json({
      code: 0,
      msg: err
    })
  }
})

// 删除接口
router.post('/deleteApi', async (req, res, next) => {
  const { id } = req.body
  await API.destroy({
    where: {
      id
    }
  })
  try {
    return res.json({
      code: 200,
      msg: '删除成功'
    })
  } catch (err) {
    return res.json({
      code: 0,
      msg: err
    })
  }
})

/* treeData */
router.get('/tree', async (req, res, next) => {
  const { projectId } = req.query
  const query = {
    projectId,
    parentId: {
      [Sequelize.Op.eq]: null
    }
  }
  const data = await Menu.findAll({
    attributes: ['id', 'name'],
    order: [['id', 'asc']],
    where: query
  })
  const result = []
  if (data.length === 0) {
    return res.json({
      code: 200,
      data: result
    })
  }
  data.forEach(async (item, i) => {
    const { id, name } = item
    result[i] = { id, name }
    const children = await Menu.findAll({
      attributes: ['id', 'name', 'parentId'],
      order: [['id', 'asc']],
      where: {
        parentId: item.id
      }
    })
    result[i].children = children
    if (i === data.length - 1) {
      $event.emit('end')
    }
  })
  $event.once('end', () => {
    res.json({
      code: 200,
      data: result
    })
  })
})
module.exports = router
